package com.log4jviewer.ui.preferences.filters;

import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;

import org.eclipse.jface.preference.IPreferenceStore;
import org.xml.sax.SAXException;

import com.log4jviewer.Activator;
import com.log4jviewer.filters.ConfigFilterLoader;
import com.log4jviewer.filters.FilterItemModel;
import com.log4jviewer.filters.FilterModel;
import com.log4jviewer.ui.preferences.DefaultPreferences;

/**
 * Class provides data for filters' preferences (filters and filter items). It also contains active filter index and
 * selected filter index in filters' table.
 * 
 * @author <a href="mailto:rd.ryly@gmail.com">Ruslan Diachenko</a> <a href="mailto:Daniil.Yaroslavtsev@gmail.com">Daniil
 *         Yaroslavtsev</a>
 */
public class FilterContentProvider {

    private final String relativeFiltersFilePath = "config/FilterPrefences.xml";

    private String absoluteFiltersFilePath;

    private List<FilterModel> filters;

    private int activeFilterIndex;

    private int selectedFilterIndex;

    public void init(final IPreferenceStore store) throws IOException,
            ParserConfigurationException, SAXException {
        filters = new ArrayList<FilterModel>();
        absoluteFiltersFilePath = Activator.getAbsolutePath(relativeFiltersFilePath);
        loadFilters();
        loadActiveFilter(store);
    }

    public String getAbsoluteFiltersFilePath() {
        return absoluteFiltersFilePath;
    }

    public List<FilterModel> getFilters() {
        return filters;
    }

    public FilterModel getActiveFilter() {
        FilterModel filterModel;

        if ((filters.size() == 0) || (activeFilterIndex < 0)) {
            filterModel = new FilterModel();
        } else {
            filterModel = filters.get(activeFilterIndex);
        }
        return filterModel;
    }

    public int getActiveFilterIndex() {
        return activeFilterIndex;
    }

    public void setActiveFilterIndex(final int activeFilterIndex) {
        this.activeFilterIndex = activeFilterIndex;
    }

    public void setSelectedFilterIndex(final int selectedFilterIndex) {
        this.selectedFilterIndex = selectedFilterIndex;
    }

    public List<FilterItemModel> getFilterItems(final int filterIndex) {
        List<FilterItemModel> filterItemModels = new LinkedList<FilterItemModel>();
        FilterModel filterModel = filters.get(filterIndex);

        for (int i = 0; i < filterModel.getItemsCount(); i++) {
            FilterItemModel filterItemModel = filterModel.getItem(i);
            filterItemModels.add(filterItemModel);
        }
        return filterItemModels;
    }

    public boolean isFilterActive(final FilterModel filterModel) {
        int currentFilterIndex = filters.indexOf(filterModel);
        boolean isFilterActive = false;

        if (currentFilterIndex == activeFilterIndex) {
            isFilterActive = true;
        }
        return isFilterActive;
    }

    private void loadFilters() throws ParserConfigurationException, SAXException, IOException {
        ConfigFilterLoader filterLoader = new ConfigFilterLoader();
        filters = filterLoader.loadFilters("file:" + absoluteFiltersFilePath);
    }

    private void loadActiveFilter(final IPreferenceStore store) {
        activeFilterIndex = store.getInt(DefaultPreferences.FilterPreferences.getId());
    }

    public FilterModel createFilter() {
        FilterModel filterModel = new FilterModel();
        filterModel.setFilterName("New Filter");
        filterModel.setFilterDescr("Default description");
        filters.add(filterModel);
        return filterModel;
    }

    public void removeFilter(final int filterIndex) {
        filters.remove(filterIndex);
    }

    public boolean isFilterListEmpty() {
        return filters.size() == 0;
    }

    public boolean isSelectedFilterContainsItems() {
        boolean isFilterContainsItems = false;

        if (!isFilterListEmpty() && isSelectedFilterIndexValid()) {
            FilterModel filterModel = filters.get(selectedFilterIndex);

            if (filterModel.getItemsCount() > 0) {
                isFilterContainsItems = true;
            }
        }
        return isFilterContainsItems;
    }

    public boolean isSelectedFilterIndexValid() {
        return ((selectedFilterIndex >= 0) && (selectedFilterIndex < filters.size()));
    }

    public FilterItemModel createFilterItem() {
        FilterItemModel filterItemModel = new FilterItemModel();
        filterItemModel.setLogicOperand(FilterItemModel.LogicOperand.AND);
        filterItemModel.setFieldType(FilterItemModel.FieldType.LEVEL);
        filterItemModel.setInclude(true);
        filterItemModel.setPattern("");
        filterItemModel.setEnabled(true);
        FilterModel selectedFilter = filters.get(selectedFilterIndex);
        selectedFilter.addItem(filterItemModel);
        return filterItemModel;
    }

    public void removeFilterItem(final int filterItemIndex) {
        FilterModel selectedFilter = filters.get(selectedFilterIndex);
        selectedFilter.removeItem(filterItemIndex);
    }
}
